import '@umijs/max';
import React, { useEffect, useState } from 'react';
import EChartsReact from 'echarts-for-react';
import { Card, Col, Divider, message, Row, Space, Statistic } from 'antd';
import { getSystemInfoUsingGet } from '@/services/api/systemInfoController';
import { ClockCircleOutlined } from '@ant-design/icons';
import {useModel} from "@@/exports";

/**
 * 系统参数管理面板
 *
 * @constructor
 */
const SystemInfoPanel: React.FC = () => {
  const { initialState } = useModel('@@initialState');
  // 是否显示加载
  const [loading] = useState<boolean>(false);

  const [data, setData] = useState<API.SystemInfo>({
    cpuLoad: 45.2,
    heapMemoryUsage: {
      used: 1024 * 1024 * 300, // 300 MB
      max: 1024 * 1024 * 1024, // 1 GB
    },
    nonHeapMemoryUsage: {
      used: 1024 * 1024 * 150, // 150 MB
      max: 1024 * 1024 * 512, // 512 MB
    },
    jvmStartTime: 1633027200000, // 示例时间戳
    jvmUptime: 3600000, // 1 小时
    totalDiskSpace: 1024 * 1024 * 1024 * 500, // 500 GB
    usedDiskSpace: 1024 * 1024 * 1024 * 200, // 200 GB
    freeDiskSpace: 1024 * 1024 * 1024 * 300, // 300 GB
  });

  const [nonHeapMemory] = useState<number[]>([]);
  const [heapMemory] = useState<number[]>([]);
  const [heapMemoryTime] = useState<string[]>([]);
  const [jvmStartTime, setJvmStartTime] = useState<object>();

  /**
   * 堆内存使用option
   */
  const getHeapMemoryOption = () => {
    const max = Number(((data.heapMemoryUsage?.max ?? 0) / (1024 * 1024)).toFixed(2));
    const committed = Number(((data.heapMemoryUsage?.committed ?? 0) / (1024 * 1024)).toFixed(2));
    const init = Number(((data.heapMemoryUsage?.init ?? 0) / (1024 * 1024)).toFixed(2));
    return {
      title: {
        text: '堆内存使用',
        subtext: committed + ' MB | ' + init + ' MB | ' + max + ' MB',
        left: 'center',
      },
      tooltip: {
        trigger: 'axis',
        formatter: '{b}: {c} MB',
      },
      xAxis: {
        type: 'category',
        data: [...heapMemoryTime], // X轴数据
      },
      yAxis: {
        type: 'value',
        axisLabel: {
          formatter: '{value} MB',
          rotate: 45,
        },
      },
      series: [
        {
          name: '堆内存使用',
          type: 'line',
          data: heapMemory,
          itemStyle: { color: '#af3c27' },
          emphasis: {
            itemStyle: {
              shadowBlur: 10,
              shadowOffsetX: 0,
              shadowColor: 'rgba(0, 0, 0, 0.5)',
            },
          },
        },
      ],
    };
  };

  /**
   * 非堆内存使用
   */
  const getNonHeapMemoryOption = () => {
    const init = Number(((data.nonHeapMemoryUsage?.init ?? 0) / (1024 * 1024)).toFixed(2));
    const committed = Number(
      ((data.nonHeapMemoryUsage?.committed ?? 0) / (1024 * 1024)).toFixed(2),
    );

    return {
      title: {
        text: '非堆内存使用',
        subtext: committed + ' MB | ' + init + ' MB',
        left: 'center',
      },
      tooltip: {
        trigger: 'axis',
        formatter: '{b}: {c} MB',
      },
      xAxis: {
        type: 'category',
        data: [...heapMemoryTime], // X轴数据
      },
      yAxis: {
        type: 'value',
        axisLabel: {
          formatter: '{value} MB',
          rotate: 40,
        },
      },
      series: [
        {
          name: '非堆内存使用',
          type: 'line',
          data: nonHeapMemory,
          itemStyle: { color: '#af3c27' },
          emphasis: {
            itemStyle: {
              shadowBlur: 10,
              shadowOffsetX: 0,
              shadowColor: 'rgba(0, 0, 0, 0.5)',
            },
          },
        },
      ],
    };
  };

  /**
   * 获取磁盘使用状况 option
   */
  const getDiskUsageOption = () => {
    const usedDiskSpace = Number(((data.usedDiskSpace ?? 0) / (1024 * 1024 * 1024)).toFixed(2));
    const totalDiskSpace = Number(((data.totalDiskSpace ?? 0) / (1024 * 1024 * 1024)).toFixed(2));
    return {
      title: {
        text: '磁盘使用',
        subtext: usedDiskSpace + ' GB / ' + totalDiskSpace + ' GB',
        left: 'center',
      },
      tooltip: {
        trigger: 'item',
        formatter: '{b}: {c} GB',
      },
      series: [
        {
          name: '磁盘使用',
          type: 'pie',
          radius: '50%',
          data: [
            { value: usedDiskSpace, name: '已使用', itemStyle: { color: '#e80808' } },
            {
              value: (totalDiskSpace - usedDiskSpace).toFixed(2),
              name: '空闲',
              itemStyle: { color: '#32CD32' },
            },
          ],
          emphasis: {
            itemStyle: {
              shadowBlur: 10,
              shadowOffsetX: 0,
              shadowColor: 'rgba(0, 0, 0, 0.5)',
            },
          },
        },
      ],
    };
  };

  const load = async () => {
    // setLoading(true);
    try {
      if (initialState?.currentUser?.userRole !== 'admin') {
        return;
      }
      const res = await getSystemInfoUsingGet();
      if (res.data) {
        setData(res.data);

        if (jvmStartTime === undefined) {
          setJvmStartTime(new Date(Number(res.data.jvmStartTime)));
        }

        // 处理时间
        if (heapMemoryTime.length > 10) {
          heapMemoryTime.shift();
        }
        heapMemoryTime.push(new Date().toLocaleTimeString());

        // 处理堆内存
        if (res.data.heapMemoryUsage) {
          const used = res.data.heapMemoryUsage.used;
          const newUsed = Number(((used ?? 0) / (1024 * 1024)).toFixed(2));
          if (heapMemory.length > 10) {
            heapMemory.shift();
          }
          heapMemory.push(newUsed);
        }
        // 处理非堆内存
        if (res.data.nonHeapMemoryUsage) {
          const used = res.data.nonHeapMemoryUsage.used;
          const newUsed = Number(((used ?? 0) / (1024 * 1024)).toFixed(2));
          if (nonHeapMemory.length > 10) {
            nonHeapMemory.shift();
          }
          nonHeapMemory.push(newUsed);
        }
      } else {
        message.success('数据为空');
      }
    } catch (e) {}

    // setLoading(false);
  };

  const getJvmRunTime = (ms: number) => {
    let seconds = Math.floor(ms / 1000);
    let minutes = Math.floor(seconds / 60);
    let hours = Math.floor(minutes / 60);
    let days = Math.floor(hours / 24);

    seconds = seconds % 60;
    minutes = minutes % 60;
    hours = hours % 24;

    return `${days}天${hours}时${minutes}分${seconds}秒`;
  };

  const getSystemRunTime = () => {
    // '2024-10-20T12:00:00Z
    // 1729425600000
    const ms = new Date().getTime() - 1729425600000;
    let seconds = Math.floor(ms / 1000);
    let minutes = Math.floor(seconds / 60);
    let hours = Math.floor(minutes / 60);
    let days = Math.floor(hours / 24);

    seconds = seconds % 60;
    minutes = minutes % 60;
    hours = hours % 24;

    return `${days}天${hours}时${minutes}分${seconds}秒`;
  };

  useEffect(() => {
    load();
  }, []);

  // 自动刷新
  let interval: string | number | NodeJS.Timeout | undefined = undefined;
  useEffect(() => {
    interval = setInterval(() => {
      load();
    }, 2000);
    return () => clearInterval(interval);
  }, []);

  return (
    <div className="systemInfoPanel">
      <Row
        gutter={{
          xs: 1,
          sm: 1,
          md: 2,
          lg: 2,
          xl: 3,
        }}
      >
        <Col xs={24} sm={24} md={12} lg={12} xl={12}>
          <Card loading={loading} title={'数据面板'}>
            <Space align={'center'} wrap>
              <div>
                <h1>蓝界航标已安全运行</h1>
                <Statistic
                  value={getSystemRunTime()}
                  valueStyle={{ color: '#c21212' }}
                  prefix={<ClockCircleOutlined />}
                />
              </div>
            </Space>
            <Divider />
            <Space wrap>
              JVM启动时间：{jvmStartTime && jvmStartTime.toLocaleString()}
              JVM运行时间：{getJvmRunTime(data.jvmUptime ?? 0)}
            </Space>
          </Card>
        </Col>
        <Col xs={24} sm={24} md={12} lg={12} xl={12}>
          <Card loading={loading}>
            <EChartsReact option={getHeapMemoryOption()} />
          </Card>
        </Col>
        <Col xs={24} sm={24} md={12} lg={12} xl={12}>
          <Card loading={loading}>
            <EChartsReact option={getNonHeapMemoryOption()} />
          </Card>
        </Col>
        <Col xs={24} sm={24} md={12} lg={12} xl={12}>
          <Card loading={loading}>
            <EChartsReact option={getDiskUsageOption()} />
          </Card>
        </Col>
      </Row>
    </div>
  );
};
export default SystemInfoPanel;
